import type { Page } from 'playwright'
import { getPageParser } from '../../shared/page-parser'

/**
 * 计算起止日期覆盖的月份列表（0基月）
 */
export function buildMonthsRange(start: Date, end: Date): Array<{ y: number, m0: number }> {
  const out: Array<{ y: number, m0: number }> = []
  let y = start.getFullYear(); let m0 = start.getMonth()
  const yEnd = end.getFullYear(); const m0End = end.getMonth()
  for (;;) {
    out.push({ y, m0 })
    if (y === yEnd && m0 === m0End)
      break
    m0++
    if (m0 > 11) { m0 = 0; y++ }
  }
  return out
}

/**
 * 将 DD-MM-YYYY 文本解析为 Date（本地时区，00:00:00）
 */
export function parseDDMMYYYY(s: string): Date {
  const [dd, mm, yyyy] = s.split('-')
  const d = new Date(Number(yyyy), Number(mm) - 1, Number(dd))
  d.setHours(0, 0, 0, 0)
  return d
}

/**
 * 读取当前日历页的 年/0基月/可用日期集合
 */
export async function readCalendar(page: Page): Promise<{ year: number, m0: number, availableDates: string[] }> {
  return await page.evaluate(() => {
    const yEl = document.querySelector('input[name="storedAppointmentCalendarYear"]') as HTMLInputElement | null
    const mEl = document.querySelector('input[name="storedAppointmentCalendarMonth"]') as HTMLInputElement | null
    let year = yEl?.value ? Number.parseInt(yEl.value, 10) : Number.NaN
    let m0 = mEl?.value ? Number.parseInt(mEl.value, 10) : Number.NaN
    const headerEl = document.querySelector('.calendar-table-header-cell') as HTMLElement | null
    const headerText = headerEl?.textContent || ''
    if (Number.isNaN(year) || Number.isNaN(m0)) {
      const mh = headerText.match(/(\d{4})年\s*(\d{1,2})月/)
      if (mh) { year = Number.parseInt(mh[1], 10); m0 = Number.parseInt(mh[2], 10) - 1 }
    }
    const availableDates: string[] = []
    document.querySelectorAll('a[onclick*="onClickDate"]').forEach((a) => {
      const oc = a.getAttribute('onclick') || ''
      const mm = oc.match(/onClickDate\('([^']+)'\)/)
      if (mm)
        availableDates.push(mm[1])
    })
    return { year, m0, availableDates }
  })
}

/**
 * 翻到指定年月（优先 onClickMonth，其次表单提交）。不包含等待逻辑。
 */
export async function gotoMonth(page: Page, year: number, m0: number): Promise<void> {
  await page.evaluate((args: { y: number, m0: number }) => {
    const { y, m0 } = args
    // 使用 setTimeout 将导航动作排入微任务之后，避免 evaluate 执行过程中上下文被销毁
    const triggerNavigate = () => {
      const doSubmit = () => {
        const frm = document.querySelector('form[name="frmAppointment"]') as HTMLFormElement | null
        if (!frm)
          return
        const ensure = (n: string, v: string) => {
          let el = frm!.querySelector(`input[name="${n}"]`) as HTMLInputElement | null
          if (!el) {
            el = document.createElement('input')
            el.type = 'hidden'
            el.name = n
            frm!.appendChild(el)
          }
          el.value = v
        }
        const office = (frm.querySelector('input[name="storedAppointmentOfficeCode"]') as HTMLInputElement | null)?.value || ''
        if (office)
          ensure('storedAppointmentOfficeCode', office)
        ensure('storedAppointmentCalendarYear', String(y))
        ensure('storedAppointmentCalendarMonth', String(m0))
        ;(frm as any).action = '/tdab2/tdabs_external/AdminServlet_tchinese?cmd=cmdGetCalendarAction'
        try { frm.submit() }
        catch {}
      }

      if (typeof (window as any).onClickMonth === 'function') {
        try { (window as any).onClickMonth(y, m0); return }
        catch {
          try { doSubmit() }
          catch {}; return
        }
      }
      try { doSubmit() }
      catch {}
    }
    try { setTimeout(triggerNavigate, 0) }
    catch { triggerNavigate() }
  }, { y: year, m0 })
}

/**
 * 解析当前月日历的统计摘要（总天数、可预约、休息日、约满、暂不可约），用于对齐自动化模块日志。
 */
export async function analyzeCalendarSummary(page: Page): Promise<{ year: number, monthIndex0: number, daysInMonth: number, availableCount: number, restCount: number, bookedCount: number, tempCount: number }> {
  const html = await page.content()
  const parser = getPageParser()
  const res = parser.parseCalendarSummary(html)
  if (res.success && res.data)
    return res.data
  throw new Error('parseCalendarSummary failed')
}
